﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YJKGeometryFuncs;
using YJKRevitDimensionText.Utility;

namespace YJKRevitDimension.SymbolTextSetting
{
	public class Ultility
	{
		public static int CalTextLength(string text)
		{
			return SpecialCharactorDrawingKit.GetLength(text);
		}

		public static double CalGridTextHeight(double d, double scale, double length, double viewscale)
		{
			return Math.Round(Math.Sqrt(Math.Pow(d, 2.0) / (1.0 + Math.Pow(scale * length, 2.0))), 5);
		}

		public static double CalGridTextScale(double d, double height, double length, double viewscale)
		{
			return Math.Round(Math.Sqrt((Math.Pow(d, 2.0) - Math.Pow(height, 2.0)) / Math.Pow(height * length, 2.0)), 5);
		}

		public static double CalIndexMarkTextHeight(double r, double scale, double length, double viewscale)
		{
			return Math.Round(Math.Sqrt(Math.Pow(r, 2.0) / (1.0 + Math.Pow(scale * length / 2.0, 2.0))), 5);
		}

		public static double CalIndexMarkTextScale(double r, double height, double length, double viewscale)
		{
			return Math.Round(2.0 * Math.Sqrt((Math.Pow(r, 2.0) - Math.Pow(height, 2.0)) / Math.Pow(height * length, 2.0)), 5);
		}

		public static bool IsExistFamily(Autodesk.Revit.DB.Document doc, string familyName, out Family family)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(Family));
			foreach (Element element in filteredElementCollector.WherePasses(elementClassFilter).ToElements())
			{
				Family family2 = element as Family;
				if (family2 != null && family2.Name == familyName)
				{
					family = family2;
					return true;
				}
			}
			family = null;
			return false;
		}

		public static bool IfTextInCircle(double circleRadis, double textHeight, double textScale, int textLength)
		{
			double num = textHeight * textScale * (double)textLength;
			double val = Math.Sqrt(Math.Pow(textHeight / 2.0, 2.0) + Math.Pow(num / 2.0, 2.0));
			return Geometry.LessThan(circleRadis, val);
		}

		public static Family GetGridFamily(Autodesk.Revit.DB.Document doc, Grid gridInput, out FamilySymbol fs)
		{
			ElementId typeId = gridInput.GetTypeId();
			GridType gridType = doc.GetElement(typeId) as GridType;
			if (gridType == null)
			{
				fs = null;
				return null;
			}
			Parameter parameter = gridType.get_Parameter(BuiltInParameter.GRID_HEAD_TAG);
			if (parameter == null)
			{
				fs = null;
				return null;
			}
			ElementId elementId = parameter.AsElementId();
			fs = (doc.GetElement(elementId) as FamilySymbol);
			return fs.Family;
		}

		public static Family GetGirdFamily(Autodesk.Revit.DB.Document doc, ElementId familySymbolId, out FamilySymbol fs)
		{
			fs = (doc.GetElement(familySymbolId) as FamilySymbol);
			return fs.Family;
		}

		public static int GetGridTextHeightAndScale(Family family, ref double textScale, ref double textHeight)
		{
			Document document = family.Document.EditFamily(family);
			if (document == null)
			{
				return -1;
			}
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(TextElement));
			IList<Element> list = filteredElementCollector.WherePasses(elementClassFilter).ToElements();
			if (list.Count <= 0)
			{
				return -2;
			}
			TextElement textElement = list.First<Element>() as TextElement;
			if (textElement == null)
			{
				return -3;
			}
			textHeight = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
			textScale = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			return 0;
		}

		public static int CreateNewFamily(Family family, double textHeight, double textScale, out string filename)
		{
			string str = string.Concat(new string[]
			{
				family.Name,
				"-",
				Math.Round(textHeight, 5).ToString(),
				"mm-",
				Math.Round(textScale, 5).ToString()
			});
			filename = Ultility.GetUserTempDirectory() + str + ".rfa";
			Document document = family.Document.EditFamily(family);
			using (Transaction transaction = new Transaction(document))
			{
				if ((int)transaction.Start("Create New FamilySymbol") != 1)
				{
					transaction.RollBack();
					filename = "";
					return -3;
				}
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
				ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(TextElement));
				IList<Element> list = filteredElementCollector.WherePasses(elementClassFilter).ToElements();
				if (list.Count <= 0)
				{
					filename = "";
					return -2;
				}
				foreach (Element element in list)
				{
					TextElement textElement = (TextElement)element;
					textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(textHeight);
					textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(textScale);
				}
				transaction.Commit();
				SaveAsOptions saveAsOptions = new SaveAsOptions();
				saveAsOptions.OverwriteExistingFile = true;
				document.SaveAs(filename, saveAsOptions);
			}
			return 0;
		}

		public static string GetUserTempDirectory()
		{
			return new DirectoryInfo(Environment.GetEnvironmentVariable("TEMP")).FullName + "\\";
		}

		public static int CreateNewFamily(Family family, double textHeight, double texScale, string familyName, out string filename)
		{
			filename = Ultility.GetUserTempDirectory() + familyName + ".rfa";
			Document document = family.Document.EditFamily(family);
			IList<Element> list = (from item in new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_GenericAnnotation)
			where item.Name == "详图编号" || item.Name == "图纸编号"
			select item).ToList<Element>();
			if (list.Count <= 0)
			{
				return -1;
			}
			foreach (Element element in list)
			{
				AnnotationSymbol annotationSymbol = element as AnnotationSymbol;
				if (annotationSymbol != null)
				{
					Document document2 = annotationSymbol.AnnotationSymbolType.Family.Document.EditFamily(annotationSymbol.AnnotationSymbolType.Family);
					FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document2);
					ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(TextElement));
					IList<Element> list2 = filteredElementCollector.WherePasses(elementClassFilter).ToElements();
					using (Transaction transaction = new Transaction(document2, "EditFamily"))
					{
						transaction.Start();
						if (list2.Count == 0)
						{
							return -2;
						}
						foreach (Element element2 in list2)
						{
							TextElement textElement = element2 as TextElement;
							if (textElement != null)
							{
								TextElementType textElementType = document2.GetElement(textElement.GetTypeId()) as TextElementType;
								if (textElementType != null)
								{
									Parameter parameter = textElementType.GetParameter(BuiltInParameter.TEXT_SIZE);
									Parameter parameter2 = textElementType.GetParameter(BuiltInParameter.TEXT_WIDTH_SCALE);
									if (parameter != null && parameter2 != null)
									{
										parameter.Set(textHeight);
										parameter2.Set(texScale);
									}
								}
							}
						}
						transaction.Commit();
					}
					document2.LoadFamily(document, new YJKFamilyOptions());
				}
			}
			SaveAsOptions saveAsOptions = new SaveAsOptions();
			saveAsOptions.OverwriteExistingFile = true;
			document.SaveAs(filename, saveAsOptions);
			return 0;
		}

		public static void DeleteFile(string filename)
		{
			if (File.Exists(filename))
			{
				File.Delete(filename);
			}
		}

		public static Family GetIndexMarkFamily(Autodesk.Revit.DB.Document doc, ElementId annotationSymbol)
		{
			return (doc.GetElement(annotationSymbol) as AnnotationSymbolType).Family;
		}

		public static int GetIndexMarkTextHeightAndScale(Family family, ref double textScale, ref double textHeight)
		{
			textScale = 0.0;
			textHeight = 0.0;
			Document document = family.Document.EditFamily(family);
			if (document == null)
			{
				return -1;
			}
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(document);
			ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(TextElement));
			IList<Element> list = filteredElementCollector.WherePasses(elementClassFilter).ToElements();
			if (list.Count <= 0)
			{
				return -2;
			}
			foreach (Element element in list)
			{
				TextElement textElement = element as TextElement;
				if (textElement != null && !(textElement.Text != Ultility.DetailNum))
				{
					textHeight = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
					textScale = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
					return 0;
				}
			}
			return -1;
		}

		public static int GetIndexMarkTextHeightAndScale1(string annotationSymbolName, Family family, ref double textScale, ref double textHeight)
		{
			textScale = 0.0;
			textHeight = 0.0;
			Document document = family.Document.EditFamily(family);
			if (document == null)
			{
				return -1;
			}
			IList<Element> list = (from item in new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_GenericAnnotation)
			where item.Name == annotationSymbolName
			select item).ToList<Element>();
			if (list.Count <= 0)
			{
				return -2;
			}
			foreach (Element element in list)
			{
				AnnotationSymbol annotationSymbol = element as AnnotationSymbol;
				if (annotationSymbol != null)
				{
					FilteredElementCollector filteredElementCollector = new FilteredElementCollector(annotationSymbol.AnnotationSymbolType.Family.Document.EditFamily(annotationSymbol.AnnotationSymbolType.Family));
					ElementClassFilter elementClassFilter = new ElementClassFilter(typeof(TextElement));
					IList<Element> list2 = filteredElementCollector.WherePasses(elementClassFilter).ToElements();
					if (list2.Count == 0)
					{
						return -3;
					}
					TextElement textElement = list2.First<Element>() as TextElement;
					textHeight = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
					textScale = textElement.Symbol.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
					return 0;
				}
			}
			return -1;
		}

		private static string DetailNum = "参数1";

		private static string DrawingNum = "参数2";
	}
}
